package org.pf.base.pfBlocks
{
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import org.farmcode.bezier.BezierPoint;
	import org.farmcode.bezier.Path;
	import org.pf.base.PFBlock;
	import org.pf.base.pfSystem.PFSystemCache;
	import org.pf.interfaces.IPFUpdater;
	import org.pf.PFPrince;
	import org.pf.base.pfGraphics.staff.DrawRopes;
	import org.pf.interfaces.IPFSystemCache;
	
	/**
	 * ...
	 * @author zeksa'
	 */
	public class PFUpdater extends PFBlock implements IPFUpdater
	{
		private var container:Sprite;
		private var _bezierPath:Path;
		private var stage:Stage;
		private var sprite:Sprite;
		
		private var _systemCache:IPFSystemCache;
		
		public function PFUpdater()
		{
			super(PFBlock.UPDATER_BLOCK);
			_bezierPath = new Path();
			
			_systemCache = PFPrince.getPrince().get_SystemCache();
			stage = _systemCache.stage;
		}
		
		private function updaterHandler(e:Event):void
		{
			update();
		}
		
		public function start():void
		{
			_systemCache.stage.addEventListener(Event.ENTER_FRAME, updaterHandler);
		}
		
		public function stop():void
		{
			var func:Function = function(e:Event):void
			{
				_systemCache.stage.removeEventListener(Event.ENTER_FRAME, func);
				_systemCache.stage.removeEventListener(Event.ENTER_FRAME, updaterHandler);
			}
			_systemCache.stage.addEventListener(Event.ENTER_FRAME, func);
		}
		
		public function update():void
		{
			_systemCache.currentWorld.Step(1 / 35, 10, 10);
			_systemCache.currentWorld.ClearForces();
			_systemCache.currentWorld.DrawDebugData();
			
			for (var b:b2Body = _systemCache.currentWorld.GetBodyList(); b; b = b.GetNext())
			{
				if (b.IsUnderCamera())
				{
					moveUnderCamera(b);
				}
				if (b.GetUserData())
				{
					if (b.GetUserData().toRemove)
					{
						_systemCache.currentWorld.DestroyBody(b);
						break;
					}
					
					if (b.GetUserData().hasImage && !b.GetUserData().bodyGraphics.inTweener)
					{
						updateSprite(b);
					}
					
					if (b.GetUserData().contactTranslocator.length != 0)
					{
						translocate(b);
					}
				}
			}
			
			if (_systemCache.currentCache && _systemCache.currentCache.ropesNames && _systemCache.currentCache.ropes)
			{
				updateRopes();
			}
		}
		
		private function moveUnderCamera(b:b2Body):void
		{
			var posX:Number;
			var posY:Number;
			
			if (_systemCache.layers.debugLayer)
			{
				posX = -b.GetWorldCenter().x * 30;
				posY = -b.GetWorldCenter().y * 30;
				
				_systemCache.layers.debugLayer.x = posX + 320;
				if (_systemCache.layers.debugLayer.x < -(_systemCache.gWidth - 630))
				{
					_systemCache.layers.debugLayer.x = -(_systemCache.gWidth - 630);
				}
				
				if (_systemCache.layers.debugLayer.x < 320 && _systemCache.layers.debugLayer.x > 0)
				{
					_systemCache.layers.debugLayer.x = 0;
				}
				
				_systemCache.layers.debugLayer.y = posY + 240;
				if (_systemCache.layers.debugLayer.y < -(_systemCache.gHeight - 480))
				{
					_systemCache.layers.debugLayer.y = -(_systemCache.gHeight - 480);
				}
				
				if (_systemCache.layers.debugLayer.y < 240 && _systemCache.layers.debugLayer.y > 0)
				{
					_systemCache.layers.debugLayer.y = 0;
				}
				
				_systemCache.layers.viewLayer.x = posX + 320;
				if (_systemCache.layers.viewLayer.x < -(_systemCache.gWidth - 630))
				{
					_systemCache.layers.viewLayer.x = -(_systemCache.gWidth - 630);
				}
				
				if (_systemCache.layers.viewLayer.x < 320 && _systemCache.layers.viewLayer.x > 0)
				{
					_systemCache.layers.viewLayer.x = 0;
				}
				
				_systemCache.layers.viewLayer.y = posY + 240;
				if (_systemCache.layers.viewLayer.y < -(_systemCache.gHeight - 480))
				{
					_systemCache.layers.viewLayer.y = -(_systemCache.gHeight - 480);
				}
				
				if (_systemCache.layers.viewLayer.y < 240 && _systemCache.layers.viewLayer.y > 0)
				{
					_systemCache.layers.viewLayer.y = 0;
				}
				
				_systemCache.layers.controlLayer.x = posX + 320;
				if (_systemCache.layers.controlLayer.x < -(_systemCache.gWidth - 630))
				{
					_systemCache.layers.controlLayer.x = -(_systemCache.gWidth - 630);
				}
				
				if (_systemCache.layers.controlLayer.x < 320 && _systemCache.layers.controlLayer.x > 0)
				{
					_systemCache.layers.controlLayer.x = 0;
				}
				
				_systemCache.layers.controlLayer.y = posY + 240;
				if (_systemCache.layers.controlLayer.y < -(_systemCache.gHeight - 480))
				{
					_systemCache.layers.controlLayer.y = -(_systemCache.gHeight - 480);
				}
				
				if (_systemCache.layers.controlLayer.y < 240 && _systemCache.layers.controlLayer.y > 0)
				{
					_systemCache.layers.controlLayer.y = 0;
				}
				
				if (_systemCache.layers.backgroundLayer)
				{
					_systemCache.layers.backgroundLayer.x = posX + 320;
					if (_systemCache.layers.backgroundLayer.x < -(_systemCache.gWidth - 630))
					{
						_systemCache.layers.backgroundLayer.x = -(_systemCache.gWidth - 630);
					}
					
					if (_systemCache.layers.backgroundLayer.x < 320 && _systemCache.layers.backgroundLayer.x > 0)
					{
						_systemCache.layers.backgroundLayer.x = 0;
					}
					
					_systemCache.layers.backgroundLayer.y = posY + 240;
					if (_systemCache.layers.backgroundLayer.y < -(_systemCache.gHeight - 480))
					{
						_systemCache.layers.backgroundLayer.y = -(_systemCache.gHeight - 480);
					}
					
					if (_systemCache.layers.backgroundLayer.y < 240 && _systemCache.layers.backgroundLayer.y > 0)
					{
						_systemCache.layers.backgroundLayer.y = 0;
					}
				}
			}
		}
		
		private function updateSprite(b:b2Body):void
		{
			sprite = b.GetUserData().bodyGraphics.sprite;
			sprite.x = b.GetPosition().x * 30
			sprite.y = b.GetPosition().y * 30;
			sprite.rotation = b.GetAngle() / Math.PI * 180;
			sprite = null;
		}
		
		private function updateRopes():void
		{
			for (var r:int = 0; r < _systemCache.currentCache.ropesNames.length; r++)
			{
				for (var d:int = 0; d < _systemCache.currentCache.ropesBodies[r].length; d++)
				{
					if (d == 0)
					{
						_systemCache.currentCache.ropes[r][1][d] = new BezierPoint(_systemCache.currentCache.ropesBodies[r][d].GetPosition().x * 30 + _systemCache.currentCache.ropes[r][0][1].x * 30, _systemCache.currentCache.ropesBodies[r][d].GetPosition().y * 30 + _systemCache.currentCache.ropes[r][0][1].y * 30);
					}
					else if (d == _systemCache.currentCache.ropesBodies[r].length - 1)
					{
						_systemCache.currentCache.ropes[r][1][d] = new BezierPoint(_systemCache.currentCache.ropesBodies[r][d].GetPosition().x * 30 + _systemCache.currentCache.ropes[r][0][2].x * 30, _systemCache.currentCache.ropesBodies[r][d].GetPosition().y * 30 + _systemCache.currentCache.ropes[r][0][2].y * 30);
					}
					else
					{
						_systemCache.currentCache.ropes[r][1][d] = new BezierPoint(_systemCache.currentCache.ropesBodies[r][d].GetPosition().x * 30, _systemCache.currentCache.ropesBodies[r][d].GetPosition().y * 30);
					}
				}
			}
			DrawRopes.draw(_systemCache.currentCache, _systemCache);
		}
		
		private function translocate(b:b2Body):void
		{
			b.SetLinearVelocity(new b2Vec2(0, 0));
			b.SetPosition(b.GetUserData().contactTranslocator.pop());
		}
	
	}

}